#!/bin/python
# -*- coding: utf-8 -*-
"""
Name: cpp_packer.py
Author: harrybao
Mail: harrybao@123u.com
Time: 2021/07/13 14:55
Desc: C++项目打包
"""

import os
import tarfile
import platform
import shutil
from path_util import PathUtil

class CppPacker:
    """C++打包类"""
    def __init__(self, project_name='sdk-framework', sdk_version='0.1.0'):
        self._project_name = project_name
        self._sdk_version = sdk_version
        pass
    
    def tarfile_name(self):
        """获取压缩包名字
        """
        return os.path.join('{0}/{1}-sdk-cpp-{2}-{3}-proxy.tar'.format(
            PathUtil().sdk_root_path, self._project_name, platform.system().lower(), self._sdk_version))

    def make_tar(self, source_path_list):
        """压缩成tar文件
        """
        output_filename = self.tarfile_name()
        with tarfile.open(output_filename, "w") as tar:
            for source_dir in source_path_list:
                print('-- packing: {0}'.format(source_dir))
                tar.add(source_dir, arcname=os.path.basename(source_dir))
    
    def add_source_file_path_recursive(self, file_path, source_path_list):
        """递归添加所有符合条件的文件"""
        for file_name in os.listdir(file_path):
            cur_path = os.path.join(file_path, file_name)
            if os.path.isdir(cur_path):
                self.add_source_file_path_recursive(cur_path, source_path_list)
            elif file_name.endswith('.h') or file_name.endswith('.hpp') or file_name.endswith('.hh'):
                source_path = os.path.join(file_path, file_name)
                source_path_list.append(source_path)
    
    def add_source_file_path(self, file_path, source_path_list):
        """添加所有符合条件的文件"""
        for file_name in os.listdir(file_path):
            cur_path = os.path.join(file_path, file_name)
            if os.path.isdir(cur_path):
                continue
            elif file_name.endswith('.h') or file_name.endswith('.hpp') or file_name.endswith('.hh'):
                source_path = os.path.join(file_path, file_name)
                source_path_list.append(source_path)


    def pack(self, include_path_list):
        """打包"""
        path_util = PathUtil()
        source_path_list = []
        for include_path in include_path_list:
            source_path_list.append(os.path.join(path_util.sdk_root_path, include_path))
        
        source_path_list.append(path_util.sdk_package_doc_path)
      
        tmp_thirdparty_path = os.path.join(path_util.sdk_root_path, '_/thirdparty')
        os.makedirs(tmp_thirdparty_path, 0o777, True)

        thirdparty_rpc_path_list = []
        thirdparty_rpc_src_path = os.path.join(path_util.sdk_thirdparty_path, 'rpc-backend-cpp', 'src')
        self.add_source_file_path(thirdparty_rpc_src_path, thirdparty_rpc_path_list)
        
        for file_path in thirdparty_rpc_path_list:
            # dir_name = os.path.basename(os.path.dirname(file_path))
            dst_path = os.path.join(tmp_thirdparty_path, 'rpc-backend-cpp')
            os.makedirs(dst_path, 0o777, True)
            shutil.copy2(file_path, dst_path)
        
        thirdparty_rpc_path_list.clear()
        thirdparty_rpc_coroutine_path = os.path.join(path_util.sdk_thirdparty_path, 'rpc-backend-cpp', 'src', 'coroutine')
        self.add_source_file_path(thirdparty_rpc_coroutine_path, thirdparty_rpc_path_list)
        for file_path in thirdparty_rpc_path_list:
            dst_path = os.path.join(tmp_thirdparty_path, 'rpc-backend-cpp/coroutine')
            os.makedirs(dst_path, 0o777, True)
            shutil.copy2(file_path, dst_path)
        
        thirdparty_rpc_path_list.clear()
        thirdparty_rpc_coroutine_path = os.path.join(path_util.sdk_thirdparty_path, 'rpc-backend-cpp/src/coroutine/detail')
        self.add_source_file_path(thirdparty_rpc_coroutine_path, thirdparty_rpc_path_list)
        for file_path in thirdparty_rpc_path_list:
            dst_path = os.path.join(tmp_thirdparty_path, 'rpc-backend-cpp/coroutine/detail')
            os.makedirs(dst_path, 0o777, True)
            shutil.copy2(file_path, dst_path)
        
        thirdparty_rpc_path_list.clear()
        thirdparty_rpc_coroutine_path = os.path.join(path_util.sdk_thirdparty_path, 'rpc-backend-cpp/src/coroutine/linux')
        self.add_source_file_path(thirdparty_rpc_coroutine_path, thirdparty_rpc_path_list)
        for file_path in thirdparty_rpc_path_list:
            dst_path = os.path.join(tmp_thirdparty_path, 'rpc-backend-cpp/coroutine/linux')
            os.makedirs(dst_path, 0o777, True)
            shutil.copy2(file_path, dst_path)
         
        thirdparty_rpc_path_list.clear()
        thirdparty_rpc_coroutine_path = os.path.join(path_util.sdk_thirdparty_path, 'rpc-backend-cpp/src/coroutine/windows')
        self.add_source_file_path(thirdparty_rpc_coroutine_path, thirdparty_rpc_path_list)
        for file_path in thirdparty_rpc_path_list:
            dst_path = os.path.join(tmp_thirdparty_path, 'rpc-backend-cpp/coroutine/windows')
            os.makedirs(dst_path, 0o777, True)
            shutil.copy2(file_path, dst_path)
 
        thirdparty_rpc_path_list.clear()
        thirdparty_knet_path = os.path.join(path_util.sdk_thirdparty_path, 'knet')
        self.add_source_file_path(thirdparty_knet_path, thirdparty_rpc_path_list)
        for file_path in thirdparty_rpc_path_list:
            dst_path = os.path.join(tmp_thirdparty_path, 'knet')
            os.makedirs(dst_path, 0o777, True)
            shutil.copy2(file_path, dst_path)
        
        tmp_sdk_framework_path = os.path.join(path_util.sdk_root_path, '_/sdk_framework')
        os.makedirs(tmp_sdk_framework_path, 0o777, True)
        tmp_sdk_framework_link_util_path = os.path.join(tmp_sdk_framework_path, 'link_util')
        os.makedirs(tmp_sdk_framework_link_util_path, 0o777, True)
        
        link_util_path = os.path.join(path_util.sdk_src_path, 'link_util')

        shutil.copy2(os.path.join(link_util_path, 'platform_link.h'), tmp_sdk_framework_link_util_path)
        shutil.copy2(os.path.join(link_util_path, 'logger.h'), tmp_sdk_framework_link_util_path)
        shutil.copy2(os.path.join(link_util_path, 'transport.h'), tmp_sdk_framework_link_util_path)
        shutil.copy2(os.path.join(path_util.sdk_src_path, 'sdk_framework.hpp'), tmp_sdk_framework_path)
        shutil.copy2(os.path.join(path_util.sdk_src_path, 'link_util_api.h'), tmp_sdk_framework_path)
 
        source_path_list.append(tmp_thirdparty_path)
        source_path_list.append(tmp_sdk_framework_path)
       
        if platform.system() == 'Windows':
            source_path_list.append('{0}/Release/{1}.dll'.format(path_util.sdk_winproj_path, self._project_name))
            pass
        else:
            source_path_list.append('{0}/build/lib{1}.so'.format(path_util.sdk_src_path, self._project_name))
            pass
        self.make_tar(source_path_list)

        shutil.rmtree(tmp_thirdparty_path)
        shutil.rmtree(tmp_sdk_framework_path)
        pass
